/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package common;

import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;

/** The format of the 10-byte packet header is as follows:
 * sequence      (1 byte )
 * checksum      (4 bytes)
 * contentLength (4 bytes)
 * flag          (1 byte )
 *
 * @author Joe
 */
public class Packet
{
    public static final int MAX_SIZE = 512; // Max size of the content field
    public static final int HEADER_SIZE = 10; // Number of bytes in the header
    public static final byte FILENAME_FLAG  = 0;
    public static final byte NORMAL_FLAG = 1;
    public static final byte END_FLAG = 2;
    public static final byte NACK_FLAG = 3;
    public static final byte ACK_FLAG = 4;
    public static final byte RESEND_FLAG = 5;
    public byte sequence;
    public int checksum;
    public int contentLength;
    public byte[] content;
    public byte flag;
    
    public Packet(byte[] rawData)
    {
        
        // Extract the packet information into fields
        try {
            ByteBuffer buffer = ByteBuffer.wrap(rawData);
            sequence = buffer.get();
            checksum = buffer.getInt();
            contentLength = buffer.getInt();
            content = new byte[contentLength];
            flag = buffer.get();
            buffer.get(content, 0, contentLength);
            
        } catch (BufferUnderflowException | IndexOutOfBoundsException e) {
            // Packet was shorter than expected
            System.err.println("Corrupted packet: " + content.length);
            System.err.println(toString());
        }
    }
    public Packet(byte[] contentData, byte seq, byte flag)
    {
        sequence = seq;
        content = contentData;
        contentLength = contentData.length;
        this.flag = flag;
        checksum = Checksum.calculate(this);
    }
    public Packet(Packet copy)
    {
        sequence = copy.sequence;
        checksum = copy.checksum;
        contentLength = copy.contentLength;
        content = copy.content;
    }
    /** Gets the byte array representation of this packet. */
    public byte[] getRaw()
    {
        byte[] raw = new byte[HEADER_SIZE + content.length];
        ByteBuffer buffer = ByteBuffer.wrap(raw);
        buffer.put(sequence);
        buffer.putInt(checksum);
        buffer.putInt(contentLength);
        buffer.put(flag);
        buffer.put(content);
        
        return buffer.array();
    }
    @Override
    public String toString()
    {
        String out = "";
        
        out += "Sequence: " + Byte.toString(sequence) + "\n";
        out += "Checksum: " + String.valueOf(checksum) + "\n";
        out += "Content Length: " + String.valueOf(contentLength) + "\n";
        out += "flag: " + Byte.toString(flag) + "\n";
                
       return out;
    }
}
